#pragma once

#define MAX_VIDEO_FRAME_IN_QUEUE    600



#include <QWidget>
#include <QIcon>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QPushButton>
#include <QHBoxLayout>
#include <Qt>
#include <QColor>
#include <QDebug>
#include "player/JCQueueDef.h"
#include <thread>
#include <QFile>
#include <QMessageBox>
#include <QImage>
#include <QLabel>
#include <QPixmap>
extern "C" {
#include<libavcodec/avcodec.h>
#include<libavformat/avformat.h>
#include<libswscale/swscale.h>
#include <libswresample/swresample.h>
#include <libavutil/imgutils.h>
};
#include "libyuv.h"

#if !defined(MIN)
#define MIN(A,B)	((A) > (B) ? (A) : (B))
#endif
typedef struct YUVChannelDef
{
	unsigned int    length;
	unsigned char* dataBuffer;

}YUVChannel;

typedef struct  YUVFrameDef
{
	unsigned int    width;
	unsigned int    height;
	YUVChannel      luma;
	YUVChannel      chromaB;
	YUVChannel      chromaR;
	long long       pts;

}YUVData_Frame;

class FFMpegSamplePlayerWindow : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
	Q_OBJECT

public:
	FFMpegSamplePlayerWindow(QWidget* parent = nullptr);
	~FFMpegSamplePlayerWindow();

protected:
	virtual void initializeGL();//初始化OpenGL
	virtual void resizeGL(int w, int h);//ResizeWindow大小
	virtual void paintGL();//绘制OpenGL
public:
	void startFFMPEG(const char* filePath);//读取文件，并获取基本信息
	void startMediaProcessThreads();//开启线程
	void doReadMediaFrameThread();//读取packet
	void doVideoDecodeShowThread();
	void stdThreadSleep(int mseconds);//休眠
	void copyDecodedFrame420(uint8_t* src, uint8_t* dist, int linesize, int width, int height);
	void updateYUVData();
	void releaseYUVData();
	void renderVideo();
private:
	//问题文件上下文
	AVFormatContext* avFormatContext = NULL;
	//解码器上下文
	AVCodecContext* avCodecContext = NULL;
	//视频流
	AVStream* avStream = NULL;

	AVRational mVideoTimeBase;//视频时间基
	int mVideoFPS = 0;//视频帧率
	//获取视频的宽高
	int mVideoWidth = 0;
	int mVideoHeight = 0;

	int videoStreamId = -1;

	bool mReadFileEOF = false;//是否读完了

	//视频队列
	JCMediaQueue<AVPacket*> mVideoPktQueue;
	AVFrame* mAVFrame = NULL;
	AVFrame* mYUVFrame = NULL;

	SwsContext* mVideoSwsCtx = NULL;

	//存放yuv的byte数组
	unsigned char* buf[3] = { 0 };
	uint8_t* m_pYUV420Buffer = NULL;
	YUVData_Frame* updateYUVFrame = NULL;


	int m_yFrameLength = 0;
	int m_uFrameLength = 0;
	int m_vFrameLength = 0;
	unsigned char* m_pBufYuv420p = NULL;
	unsigned char* yuvBuffer = NULL;

private://opengl相关代码
	unsigned int VAO, VBO, EBO;
	unsigned int textures[3];
	GLuint programId;

	//以下三个默认是4x4单位矩阵
	QMatrix4x4 uModelMatrix;
	QMatrix4x4 uViewMatrix;
	QMatrix4x4 uProjectionMatrix;
public:
	GLuint getShaderId(GLenum shaderType, QString resPath);
	GLuint buildAttachShaderAndReturnProgramId(QString vertexResPath, QString fragmentResPath);
	void getLinkProgramErrorInfo(GLuint programId);
	void getCompileShaderErrorInfo(GLuint shaderId);
	QString getTexturePath(QString textureImageName);

	///信号槽
signals:
	void sendSignalsImage(const QImage &img);

	//public slots:
	//	void receiveSlotsImage();

};

